定期ミートアップ 第62回
milika
async ifを実装した
https://github.com/yhara/milika/pull/10
code:txt
extern print(Int n) -> Null
extern(async) sleep_sec(Int n) -> Null
fun chiika_main() -> Null {
print(
if (true) {
sleep_sec(1)
yield 456
} else {
yield 789
}
)
return null
}
yieldは、MLIRのscf.yieldに対応
lower_async_if.rs
ifを、「trueのときの関数」「falseのときの関数」「ifよりあとの関数」に分割
code:txt
fun chiika_main?() -> Null {
cond_return true, chiika_main't?(...), chiika_main'f?(...) #-> Void
}
fun chiika_main't?() -> Null {
sleep_sec*(1) #-> Null
return chiika_main'e?(456) # Null #-> Void
}
fun chiika_main'f?() -> Null {
return chiika_main'e?(789) # Null #-> Void
}
fun chiika_main'e?(Int $ifResult) -> Null {
print+(%arg_0) #-> Null
return null # Null #-> Void
}
asyncness_check.rs
各関数のsync(下記の[+]マーク)とasync([*])を判定
判定はconservative
code:txt
fun chiika_main*() -> Null {
cond_return true, chiika_main't*(...), chiika_main'f+(...) #-> Void
}
fun chiika_main't*() -> Null {
sleep_sec*(1) #-> Null
return chiika_main'e+(456) # Null #-> Void
}
fun chiika_main'f+() -> Null {
return chiika_main'e+(789) # Null #-> Void
}
fun chiika_main'e+(Int $ifResult) -> Null {
print+(%arg_0) #-> Null
return null # Null #-> Void
}
async_splitter.rs
asyncな関数を、async callを境に分割
あと、cond_return命令をif式に戻しつつ、必要に応じてtrue関数・false関数の呼び出しをcps対応
code:txt
fun chiika_main.(ChiikaEnv $env, (ChiikaEnv,Null)->RustFuture $cont) -> RustFuture {
return if(true){
yield chiika_main't.(%arg_0, %arg_1) # RustFuture
} else {
yield %arg_1.(%arg_0, chiika_main'f+()) # RustFuture
} # RustFuture #-> Void
}
fun chiika_main't.(ChiikaEnv $env, (ChiikaEnv,Null)->RustFuture $cont) -> RustFuture {
chiika_env_push.(%arg_0, FunToAny(%arg_1)) #-> Int
return sleep_sec.(%arg_0, chiika_main't_1, 1) # RustFuture #-> Void
}
fun chiika_main't_1.(ChiikaEnv $env, Null $async_result) -> RustFuture {
%arg_1 #-> Null
return AnyToFun((ChiikaEnv,Null)->RustFuture)(chiika_env_pop.(%arg_0, 1)).(%arg_0, chiika_main'e+(456)) # RustFuture #-> Void
}
fun chiika_main'f.() -> Null {
return chiika_main'e+(789) # Null #-> Void
}
fun chiika_main'e.(Int $ifResult) -> Null {
print+(%arg_0) #-> Null
return null # Null #-> Void
}
lower_if.rs
if式をcf.cond_brに変換
scf.ifはfunc.returnを内包できないため`
code:txt
fun chiika_main(ChiikaEnv $env, (ChiikaEnv,Null)->RustFuture $cont) -> RustFuture {
%cond_br true ^bb1 ^bb2; #-> Void
^bb1()
%br ^bb3(chiika_main't.(%arg_0, %arg_1)) # RustFuture; #-> Void
^bb2()
%br ^bb3(%arg_1.(%arg_0, chiika_main'f+())) # RustFuture; #-> Void
^bb3(RustFuture)
return %block_arg # RustFuture; #-> Void
}
...
async whileを実装したい
自己再帰にloweringすることを考えている
→自己再帰で無限ループできる(stack overflowしない)ことが必要
.llがtail callになっていればよさそう?
#定期ミートアップ